package top.hcode.hoj.dao;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import top.hcode.hoj.common.LazyDao;
import top.hcode.hoj.mapper.CollQuestionMapper;
import top.hcode.hoj.pojo.entity.coll.CollQuestion;
import top.hcode.hoj.pojo.entity.coll.CollQuestionOption;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author orangej
 * @since 2025-02-09
 */
@Service
@RequiredArgsConstructor
public class CollQuestionDao extends ServiceImpl<CollQuestionMapper, CollQuestion> {
    private final LazyDao dao;

    @Cached(cacheType = CacheType.BOTH)
    public CollQuestion getByIdWithCache(String questionId) {
        return getById(questionId);
    }

    @Cached(cacheType = CacheType.BOTH)
    public List<String> querySubjectiveQuestionIdList(String collId) {
        return lambdaQuery()
                .select(CollQuestion::getId)
                .eq(CollQuestion::getCollId, collId)
                .in(CollQuestion::getQuestionType, 4)
                .list()
                .stream()
                .map(CollQuestion::getId)
                .collect(Collectors.toList());
    }

    @Cached(cacheType = CacheType.BOTH)
    public List<CollQuestion> queryByCollId(String collId) {
        return lambdaQuery()
                .eq(CollQuestion::getCollId, collId)
                .orderByAsc(CollQuestion::getSortOrder)
                .list();
    }

    /**
     * 查询题目答案：{questionId, answer}
     * 单选题：{questionId, optionId}
     * 多选题：{questionId, optionId1, optionId2, ...}
     * 填空题：{questionId, optionContent}
     *
     * @param questionIdList 题目ID列表
     * @return 题目答案Map
     */
    @Cached(cacheType = CacheType.BOTH)
    public Map<String, String> queryQuestionAnswerMap(List<String> questionIdList) {
        List<CollQuestionOption> optionList = dao.selectList(CollQuestionOption.class,
                "select * from coll_question_option where " +
                "question_id in (?) and is_answer = 1 order by id", questionIdList);

        Map<String, String> result = new HashMap<>();
        for (CollQuestionOption option : optionList) {
            String questionId = option.getQuestionId();
            String id = option.getId();
            if (result.containsKey(questionId)) {
                // 多选题答案
                String answer = result.get(questionId);
                result.put(questionId, answer + "," + id);
            } else if (StrUtil.isNumeric(option.getOptionNum())) {
                // 填空题
                result.put(questionId, option.getContent());
            } else {
                // 选择题
                result.put(questionId, id);
            }
        }

        return result;
    }

    /**
     * 查询指定活动的客观题答案：{questionId, answer}
     *
     * @param collId 活动ID
     * @return 客观题答案Map，参考queryQuestionAnswerMap
     */
    @Cached(cacheType = CacheType.BOTH)
    public Map<String, String> queryObjectiveQuestionAnswerMap(String collId) {
        List<String> questionIdList = dao.queryString("select id from coll_question where coll_id = ? and question_type in (1,2,3)", collId);
        return queryQuestionAnswerMap(questionIdList);
    }

    // 是否多选题
    @Cached(cacheType = CacheType.BOTH, expire = 300)
    public boolean isMultiChoice(String questionId) {
        return lambdaQuery()
                       .select(CollQuestion::getId)
                       .eq(CollQuestion::getId, questionId)
                       .eq(CollQuestion::getQuestionType, 2)
                       .count() > 0;
    }

    public Integer getMaxSortOrder(String collId) {
        Integer order = dao.fetchInt("select MAX(sort_order) from coll_question where coll_id = ?", collId);
        return ObjectUtil.defaultIfNull(order, 0);
    }

    /**
     * 查询指定活动是否存在主观题
     *
     * @param collId 活动ID
     * @return 是否存在主观题
     */
    @Cached(cacheType = CacheType.BOTH, expire = 300)
    public boolean isCollHasSubjectiveQuestion(String collId) {
        return dao.fetchInt("select count(1) from coll_question where coll_id = ? and question_type >= 4", collId) > 0;
    }
}
